package com.sd.common.utils.cti;

import com.sd.common.utils.Converters;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class TypeConverter {
    private final Map<Class<?>, IConverter<?>> converterMap = new HashMap(64);
    private static TypeConverter me = new TypeConverter();

    private TypeConverter() {
        this.regist(Integer.class, new Converters.IntegerConverter());
        this.regist(Integer.TYPE, new Converters.IntegerConverter());
        this.regist(Long.class,new Converters.LongConverter());
        this.regist(Long.TYPE, new Converters.LongConverter());
        this.regist(Double.class, new Converters.DoubleConverter());
        this.regist(Double.TYPE, new Converters.DoubleConverter());
        this.regist(Float.class, new Converters.FloatConverter());
        this.regist(Float.TYPE, new Converters.FloatConverter());
        this.regist(Boolean.class, new Converters.BooleanConverter());
        this.regist(Boolean.TYPE, new Converters.BooleanConverter());
        this.regist(Date.class, new Converters.DateConverter());
        this.regist(java.sql.Date.class, new Converters.SqlDateConverter());
        this.regist(Time.class, new Converters.TimeConverter());
        this.regist(Timestamp.class, new Converters.TimestampConverter());
        this.regist(BigDecimal.class, new Converters.BigDecimalConverter());
        this.regist(BigInteger.class, new Converters.BigIntegerConverter());
        this.regist(byte[].class, new Converters.ByteArrayConverter());
        this.regist(Short.class, new Converters.ShortConverter());
        this.regist(Short.TYPE, new Converters.ShortConverter());
        this.regist(Byte.class, new Converters.ByteConverter());
        this.regist(Byte.TYPE, new Converters.ByteConverter());
    }

    public static TypeConverter me() {
        return me;
    }

    public <T> void regist(Class<T> type, IConverter<T> converter) {
        this.converterMap.put(type, converter);
    }

    public final Object convert(Class<?> type, String s) throws ParseException {
        if (s == null) {
            return null;
        } else if (type == String.class) {
            return "".equals(s) ? null : s;
        } else {
            s = s.trim();
            if ("".equals(s)) {
                return null;
            } else {
                IConverter<?> converter = (IConverter)this.converterMap.get(type);
                if (converter != null) {
                    return converter.convert(s);
                }{
                    throw new RuntimeException(type.getName() + " can not be converted, please use other type of attributes in your model!");
                }
            }
        }
    }
}
